package com.aote.serialnumber;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.WeakHashMap;

import com.browsesoft.dbtools.DBTools;

public class IncreaseSerialFactory {
	private static IncreaseSerialFactory self = new IncreaseSerialFactory();

	/**
	 * 表名
	 */
	private static String tableName = "f_serialnumber";

	/**
	 * 序列
	 */
	private Map serials = new HashMap();

	/**
	 * 所有对象
	 */
	private Map takers = new WeakHashMap();

	private IncreaseSerialFactory() {

	}

	public static IncreaseSerialFactory getInstance() {
		return self;
	}

	/**
	 * 得到编号
	 */
	public IncreaseSerialNumber getSerialNumber(String name, Object taker) {
		Taker tak = (Taker) this.takers.get(taker);
		if (tak == null) {
			tak = new Taker();
			takers.put(taker, tak);
		}
		IncreaseSerialNumber number = this.getSerialNumber(name);
		tak.addNumber(number);
		return number;
	}

	/**
	 * 更新编号
	 * 
	 * @param taker
	 */
	public Map updateSerialNumber(Object taker) {
		Taker t = (Taker) this.takers.get(taker);
		if (t == null) {
			return null;
		}
		Map result = t.updateNumbers();
		this.takers.remove(taker);
		return result;
	}

	/**
	 * 得到编号
	 * 
	 * @param name
	 * @return
	 */
	public IncreaseSerialNumber getSerialNumber(String name) {
		IncreaseSerialNumber number = (IncreaseSerialNumber) serials.get(name);
		if (number != null) {
			return number;
		}
		number = load(name);
		this.serials.put(name, number);
		return number;
	}

	/**
	 * 装载数据
	 */
	private IncreaseSerialNumber load(String name) {
		try {
			// 如果表不存在
			if (!DBTools.isTableExist(tableName)) {
				IncreaseSerialNumber number = new IncreaseSerialNumber(name);
				number.insert();
				return number;
			}
			// 得数据
			String[][] datas = getDatas(name);
			// 如果没有改数据
			if (datas.length < 2) {
				IncreaseSerialNumber number = new IncreaseSerialNumber(name);
				number.insert();
				return number;
			}
			// 有数据,加载数据
			else {
				Hashtable table = DBTools.getAttributes(datas, 1);
				IncreaseSerialNumber number = new IncreaseSerialNumber(table);
				return number;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 根据名称得数据
	 */
	private String[][] getDatas(String name) throws Exception {
		String sql = "select * from " + tableName + " where id = '" + name
				+ "'";
		return DBTools.executeQueryWithTableHead(sql);
	}

	private class Taker {
		private LinkedList link = new LinkedList();

		public Taker() {
		}

		/**
		 * 添加编号
		 * 
		 * @param number
		 */
		public void addNumber(IncreaseSerialNumber number) {
			this.link.add(number);
		}

		/**
		 * 更新编号
		 * 
		 */
		public Map updateNumbers() {
			Map result = new HashMap();
			Iterator iter = link.iterator();
			while (iter.hasNext()) {
				IncreaseSerialNumber number = (IncreaseSerialNumber) iter
						.next();
				number.updateNum();
				String name = number.getNumberName();
				String num = number.getLastNumber();
				result.put(name, num);
			}
			return result;
		}
	}
}
